package com.example.demo.realm;


import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

/**
 * <p>对定义的权限进行扩展,主要对or,and,not等关键字逆行判断</p>
 * <p>暂未使用</p>
 * <p>@author Henry.Y</p>
 * <p>@date 2019-08-30</p>
 */
public class ShiroTagsReam extends AuthorizingRealm{
	
	private static final String OR_OPERATOR= "or";
	
	private static final String AND_OPERATOR= "and";
	
	private static final String NOT_OPERATOR= "not";

	/**
	 * 重写权限验证方法
	 */
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection princpals){
		
		
		return null;
	}
	
	/**
	 * 重写省份验证方法
	 */
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token){
		
		String username= (String)token.getPrincipal();
		String password= new String((char[])token.getCredentials());
		if(!"zhang".equals(username)){			
			throw new UnknownAccountException();
		}
		if(!"123".equals(password)){
			throw new IncorrectCredentialsException();
		}
		return new SimpleAuthenticationInfo(username,password,getName());
	}
	
	/**
	 * <p>支持 and or not关键字的检校,不支持and or混用</p>
	 * <p>扩展重新验证权限类方法,or表示”或“,and表示”且“</p>
	 * @param principals 账户信息集合
	 * @param permission 权限信息
	 */
	public boolean isPermitted(PrincipalCollection principals,String permission){
		if(permission.contains(OR_OPERATOR)){
			String[] permissions= permission.split(OR_OPERATOR);
			for(String orPermission:permissions){
				if(isPermittedWithNotOperator(principals,orPermission)){
					return true;
				}
			}
			return false;
		}else if(permission.contains(AND_OPERATOR)){
			String[] permissions= permission.split(AND_OPERATOR);
			for(String andPermission:permissions){
				if(isPermittedWithNotOperator(principals,andPermission)){
					return true;
				}
			}
			return false;
		}else{
			return isPermittedWithNotOperator(principals,permission);
		}
		
	}
	
	/**
	 * <p>判断是否包含not关键字,如果包含则取点该关键字在进行检校</p>
	 * <p>如果不包含not关键字，直接调用父类的方法进行检校</p>
	 * @param principals 行胡信息集合
	 * @param permission 权限字符串
	 * @return
	 */
	private boolean isPermittedWithNotOperator(PrincipalCollection principals,String permission){
		if(permission.startsWith(NOT_OPERATOR)){
			return !super.isPermitted(principals, permission.substring(NOT_OPERATOR.length()));
		}else{
			return super.isPermitted(principals,permission);
		}
	}
}
